import { getDynamicProps } from "@/utils";
import { isProdMode } from "@/utils/env";
import { error } from "@/utils/log";
import { onUnmounted, ref, toRaw, unref, watch, WatchStopHandle } from "vue";
import { FormActionType } from "@/components/Form/src/types/form";
import {
  BasicColumn,
  BasicTableProps,
  FetchParams,
  GetColumnsParams,
  TableActionType,
} from "../types/table";
import { Nullable, Recordable } from "/#/global";
import type { DynamicProps } from "/#/utils";

type Props = Partial<DynamicProps<BasicTableProps>>;
export type UseTableMethod = TableActionType & {
  getForm?: () => FormActionType;
};

export function useTable(tableProps?: Props): [
  (instance: TableActionType, formInstance: UseTableMethod) => void,
  TableActionType & {
    getForm: () => FormActionType;
  }
] {
  const tableRef = ref<Nullable<TableActionType>>(null);
  const loadedRef = ref<Nullable<boolean>>(false);
  const formRef = ref<Nullable<UseTableMethod>>(null);
  let stopWatch: WatchStopHandle;

  //注册表格props
  function register(instance: TableActionType, formInstance: UseTableMethod) {
    isProdMode() &&
      onUnmounted(() => {
        tableRef.value = null;
        loadedRef.value = null;
      });

    if (unref(loadedRef) && isProdMode() && instance === unref(tableRef))
      return;

    tableRef.value = instance;
    formRef.value = formInstance;

    tableProps && instance.setProps(getDynamicProps(tableProps));
    loadedRef.value = true;

    stopWatch?.();

    stopWatch = watch(
      () => tableProps,
      () => {
        tableProps && instance.setProps(getDynamicProps(tableProps));
      },
      {
        immediate: true,
        deep: true,
      }
    );
  }

  function getTableInstance(): TableActionType {
    const table = unref(tableRef);
    if (!table) {
      error(
        "The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!"
      );
    }
    return table as TableActionType;
  }

  const methods: TableActionType & {
    getForm: () => FormActionType;
  } = {
    getForm: () => {
      return unref(formRef) as unknown as FormActionType;
    },
    setProps: (props: Partial<BasicTableProps>) => {
      getTableInstance().setProps(props);
    },
    scrollTo: (pos: string) => {
      // getTableInstance().scrollTo(pos);
    },
    reload: async (opt?: FetchParams) => {
      return await getTableInstance().reload(opt);
    },
    getColumns: (opt?: GetColumnsParams) => {
      return getTableInstance().getColumns(opt);
    },
    setColumns: (columnList: Partial<BasicColumn<any>>[] | string[]) => {
      getTableInstance().setColumns(columnList);
    },
    getCacheColumns: () => {
      return toRaw(getTableInstance().getCacheColumns());
    },
    getRowSelection: () => {
      return toRaw(getTableInstance().getRowSelection());
    },
    setLoading: (loading: boolean) => {
      getTableInstance().setLoading(loading);
    },
    getDataSource: () => {
      return getTableInstance().getDataSource();
    },
    updateTableDataRecord: (rowKey: string | number, record: Recordable) => {
      return getTableInstance().updateTableDataRecord(rowKey, record);
    },
    deleteTableDataRecord:(rowKey: string | number) => {
      return getTableInstance().deleteTableDataRecord(rowKey);
    },
    getPaginationRef: () => {
      return getTableInstance().getPaginationRef();
    },
    setPagination: (info: Partial<PaginationProps>) => {
      return getTableInstance().setPagination(info);
    },
  };

  return [register, methods];
}
